package com.gccloud.design.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gccloud.design.dao.FormTempDao;
import com.gccloud.design.dao.LinkComponentsDao;
import com.gccloud.design.dto.BwpActivityRepoDto;
import com.gccloud.design.dto.PageObj;
import com.gccloud.design.entity.BwpActivityRepoEntity;
import com.gccloud.design.entity.FormTempEntity;
import com.gccloud.design.entity.OptButtonBranchEntity;
import com.gccloud.design.service.LinkComponentsService;
import com.gccloud.design.vo.FormTempVo;
import com.gccloud.design.vo.OptButtonBranchVo;
import com.gccloud.starter.common.exception.GlobalException;
import com.gccloud.starter.common.utils.BeanConvertUtils;
import com.gccloud.starter.common.vo.R;
import com.gccloud.starter.feign.api.service.ISysUserService;
import com.google.common.collect.Lists;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 实现功能：环节组件增删改操作
 *
 * @author Administrator
 */
@Service
public class LinkComponentsServiceImpl extends ServiceImpl<LinkComponentsDao, BwpActivityRepoEntity> implements LinkComponentsService {

    private static final String REPO_ID = "repo_";

    private final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory.getLogger(LinkComponentsService.class);

    @Resource
    private ISysUserService iSysUserService;

    @Resource
    private LinkComponentsDao linkComponentsDao;

    @Resource
    private FormTempDao formTempDao;


    /**
     * db查询树数据，获取业务类型
     */
    @Override
    public List<Map<String, Object>> getDataByParentId() {
        LOGGER.info("=================db查询树数据，获取业务类型=================");
        return linkComponentsDao.getDataByParentId();
    }

    /**
     * db查询环节组件
     */
    @Override
    public Map<String, Object> getDataList(BwpActivityRepoDto bwpActivityRepoDto) {
        LOGGER.info("=================db查询环节组件=================");
        Map<String, Object> map = new HashMap<>();
        Page<BwpActivityRepoEntity> page = new Page<>(bwpActivityRepoDto.getPage(), bwpActivityRepoDto.getRows());
        map.put("list", linkComponentsDao.getDataList(bwpActivityRepoDto.getRepoId(), bwpActivityRepoDto.getActivityName(), bwpActivityRepoDto.getActivityType(), bwpActivityRepoDto.getBusinessTypeId(), page));
        map.put("total", page.getTotal());
        return map;
    }

    /**
     * db查询环节绑定操作
     */
    @Override
    public List<OptButtonBranchVo> getBind(String repoId) {
        List<OptButtonBranchVo> bindList = new ArrayList<>();
//        通过repoId查询出操作列表
        String operationList = linkComponentsDao.getOperation(repoId);
//        将列表转换为list
        List<Map<String, String>> idMapList = JSONObject.parseObject(operationList, new TypeToken<Object>() {
        }.getType());
//        遍历获取id，查询，并存入list
        if ("".equals(operationList) || operationList == null) {
            return null;
        } else {
            for (Map<String, String> stringStringMap : idMapList) {
                String id = stringStringMap.get("id");
                OptButtonBranchEntity optButtonBranchEntity = linkComponentsDao.getBind(id);
                OptButtonBranchVo optButtonBranchVo = BeanConvertUtils.convert(optButtonBranchEntity, OptButtonBranchVo.class);
                bindList.add(optButtonBranchVo);
            }
        }
        return bindList;
    }

    /**
     * db获取执行逻辑和补偿逻辑
     */
    @Override
    public Map<String, Object> getMethod(String type) {
        Map<String, Object> methodMap = new HashMap<>();
        methodMap.put("list", linkComponentsDao.getMethod(type));
        return methodMap;
    }

    /**
     * db查询绑定弹窗
     */
    @Override
    public Map<String, Object> getBindForm(String repoId, String optBranchCode, String optBranchName, PageObj pageObj) {
        //通过repoId查询出操作列表
        String operation = linkComponentsDao.getOperation(repoId);
        //通过repoId查出businessTypeId
        Integer businessTypeId = linkComponentsDao.getBusinessTypeId(repoId);
        //绑定查询
        Page<OptButtonBranchEntity> page = new Page<>(pageObj.getPage(), pageObj.getRows());
        List<OptButtonBranchEntity> list = linkComponentsDao.getBindList(businessTypeId, optBranchCode, optBranchName, page);
        //json转为list
        List<Map<String, String>> idMapList = JSONObject.parseObject(operation, new TypeToken<Object>() {
        }.getType());
        //从list map 中取出id存入newlist
        List<String> newList = new ArrayList<>();
        List<OptButtonBranchVo> optButtonBranchVoList = Lists.newArrayList();
        if ("".equals(operation) || operation == null) {
            for (OptButtonBranchEntity optButtonBranchEntity : list) {
                OptButtonBranchVo optButtonBranchVo = BeanConvertUtils.convert(optButtonBranchEntity, OptButtonBranchVo.class);
                optButtonBranchVo.setIsBind("未绑定");
                optButtonBranchVoList.add(optButtonBranchVo);
            }
        } else {
            for (Map<String, String> stringStringMap : idMapList) {
                newList.add(stringStringMap.get("id"));
            }
            for (OptButtonBranchEntity optButtonBranchEntity : list) {
                OptButtonBranchVo optButtonBranchVo = BeanConvertUtils.convert(optButtonBranchEntity, OptButtonBranchVo.class);
                if (newList.contains(String.valueOf(optButtonBranchEntity.getOptBranchId()))) {
                    optButtonBranchVo.setIsBind("已绑定");
                } else {
                    optButtonBranchVo.setIsBind("未绑定");
                }
                optButtonBranchVoList.add(optButtonBranchVo);
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("list", optButtonBranchVoList);
        map.put("total", page.getTotal());
        return map;
    }


    /**
     * db查询页面模板
     */
    @Override
    public Map<String, Object> getForm(Integer businessTypeId, String repoId) {
        Map<String, Object> formMap = new HashMap<>();
        //根据businessTypeId查询所有模板
        QueryWrapper<FormTempEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("BUSINESS_TYPE_ID", businessTypeId);
        List<FormTempEntity> formTempEntityList = formTempDao.selectList(wrapper);
        //根据repoId查询当前环节
        QueryWrapper<BwpActivityRepoEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("REPO_ID", repoId);
        BwpActivityRepoEntity bwpActivityRepoEntity = linkComponentsDao.selectOne(queryWrapper);
        Integer formId = bwpActivityRepoEntity.getFormId();
        List<FormTempVo> list = new ArrayList<>();
        for (FormTempEntity entityList : formTempEntityList) {
            Integer formIds = entityList.getFormId();
            FormTempVo formTempVo = new FormTempVo();
            if (formId == 0) {
                formTempVo.setIsSelect("未绑定");
            } else if (formIds.equals(formId)) {
                formTempVo.setIsSelect("已绑定");
            } else {
                formTempVo.setIsSelect("未绑定");
            }
            formTempVo.setId(entityList.getFormId());
            formTempVo.setName(entityList.getFormName());
            formTempVo.setFormDes(entityList.getFormDes());
            formTempVo.setBusinessTypeId(entityList.getBusinessTypeId());
            formTempVo.setBusinessTypeName(bwpActivityRepoEntity.getBusinessTypeName());
            list.add(formTempVo);
        }
        formMap.put("list", list);
        return formMap;
    }

    /**
     * db查重环节名称
     */
    @Override
    public boolean repeatActivityName(Integer businessTypeId, String activityName, String repoId) {
        LOGGER.info("=================db查重环节名称=================");
        int count = 0;
        LambdaQueryWrapper<BwpActivityRepoEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BwpActivityRepoEntity::getBusinessTypeId, businessTypeId);
        queryWrapper.eq(BwpActivityRepoEntity::getActivityName, activityName);
        if (!Objects.equals(repoId, "") && repoId != null) {
            queryWrapper.ne(StringUtils.isNotBlank(repoId), BwpActivityRepoEntity::getRepoId, repoId);
        }
        count = count(queryWrapper);
        return count > 0;
    }

    /**
     * db绑定模板 :查重绑定formId
     */
    @Override
    public BwpActivityRepoEntity checkFormId(String repoId) {
        LOGGER.info("=================db绑定模板 :查重绑定formId=================");
        QueryWrapper<BwpActivityRepoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("REPO_ID", repoId);
        return linkComponentsDao.selectOne(wrapper);
    }

    /**
     * es取消模板 :查寻绑定的formId
     */
    @Override
    public List<BwpActivityRepoEntity> getFormId(String repoId, Integer formId) {
        LOGGER.info("=================es取消模板 :查寻绑定的formId=================");
        QueryWrapper<BwpActivityRepoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("FORM_ID", formId).eq("REPO_ID", repoId);
        return linkComponentsDao.selectList(wrapper);
    }

    /**
     * 查询出已绑定的模板
     */
    @Override
    public BwpActivityRepoEntity getOperation(String repoId) {
        LOGGER.info("=================db查询出已绑定的模板=================");
        QueryWrapper<BwpActivityRepoEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("REPO_ID", repoId);
        return linkComponentsDao.selectOne(wrapper);
    }

    /**
     * 新增/修改 保存操作
     */
    @Override
    public void saveActivityRepo(BwpActivityRepoDto bwpActivityRepoDto) {
        BwpActivityRepoEntity bwpActivityRepoEntity = BeanConvertUtils.convert(bwpActivityRepoDto, BwpActivityRepoEntity.class);
        bwpActivityRepoEntity.setActivityId("");
        bwpActivityRepoEntity.setActivityType(bwpActivityRepoDto.getAutoOrManual());
        bwpActivityRepoEntity.setContent(bwpActivityRepoDto.getDescription());
        bwpActivityRepoEntity.setOperationList("");
        bwpActivityRepoEntity.setVersion("1");
        bwpActivityRepoEntity.setDelFlag(0);
        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        bwpActivityRepoEntity.setCreateTime(sf.format(date));
        bwpActivityRepoEntity.setCreateUser(iSysUserService.getCurrentUser().getData().getName());
        bwpActivityRepoEntity.setUpdateTime(sf.format(date));
        bwpActivityRepoEntity.setUpdateUser(iSysUserService.getCurrentUser().getData().getName());
        bwpActivityRepoEntity.setShardingId(0);
        if (bwpActivityRepoDto.getFormId() == null) {
            bwpActivityRepoEntity.setFormId(0);
        }
        if (bwpActivityRepoDto.getRepoId() == null || "".equals(bwpActivityRepoDto.getRepoId())) {
            LOGGER.info("开始新增操作");
            String sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
            bwpActivityRepoEntity.setRepoId(REPO_ID + sdf);
            //db
            dbRepeatActivityName(bwpActivityRepoDto.getBusinessTypeId(), bwpActivityRepoDto.getActivityName(), bwpActivityRepoDto.getRepoId());
            linkComponentsDao.insert(bwpActivityRepoEntity);
            LOGGER.info("db新增操作成功");

        } else {
            LOGGER.info("开始修改操作");
            bwpActivityRepoEntity.setVersion(String.valueOf(Integer.parseInt(bwpActivityRepoEntity.getVersion()) + 1));
            //db
            dbRepeatActivityName(bwpActivityRepoDto.getBusinessTypeId(), bwpActivityRepoDto.getActivityName(), bwpActivityRepoDto.getRepoId());
            UpdateWrapper<BwpActivityRepoEntity> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("REPO_ID", bwpActivityRepoEntity.getRepoId());
            linkComponentsDao.update(bwpActivityRepoEntity, updateWrapper);
            LOGGER.info("db修改操作成功");

        }
    }

    /**
     * 批量删除环节组件
     */
    @Override
    public void batchDelete(String ids) {
        String[] strArr = ids.split(",");
        for (String id : strArr) {
            //db
            linkComponentsDao.batchDelete(id);
            LOGGER.info("db批量删除环节组件成功");

        }
    }

    /**
     * 绑定模板
     */
    @Override
    public void selectForm(String repoId, Integer id) {
        //db
        dbCheckFormId(repoId);
        linkComponentsDao.addFormId(repoId, id);
        LOGGER.info("db绑定模板成功");

    }

    /**
     * 取消绑定模板
     */
    @Override
    public R<Object> noBindForm(String repoId, Integer id) {
        //db
        List<BwpActivityRepoEntity> dbList = this.getFormId(repoId, id);
        BwpActivityRepoEntity entity = dbList.get(0);
        LambdaUpdateWrapper<BwpActivityRepoEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(BwpActivityRepoEntity::getRepoId, repoId)
                .set(BwpActivityRepoEntity::getFormId, 0);
        linkComponentsDao.update(entity, updateWrapper);
        LOGGER.info("db取消绑定模板成功");
        return R.success();
    }

    /**
     * 绑定环节操作
     */
    @Override
    public void updateActivity(String repoId, String ids) {
        //分割字符串
        String[] strArr = ids.split(",");
        //db
        BwpActivityRepoEntity dbEntity = this.getOperation(repoId);
        String dbOperationList = dbEntity.getOperationList();
        List<String> dbIdList = new ArrayList<>();
        List<Map<String, String>> dbIdMapList = new ArrayList<>();
        if (!Objects.equals(dbOperationList, "") && dbOperationList != null) {
            // 将列表转换为list
            dbIdMapList = JSONObject.parseObject(dbOperationList, new TypeToken<Object>() {
            }.getType());
            for (Map<String, String> map : dbIdMapList) {
                dbIdList.add(map.get("id"));
            }
        }
        //遍历存入list
        for (String id : strArr) {
            if (!dbIdList.contains(id)) {
                dbIdMapList.add(new HashMap<String, String>() {
                    private static final long serialVersionUID = 1699587959484023122L;

                    {
                        put("id", id);
                    }
                });
            }
        }
        //list转json
        String dbJson = JSONArray.toJSONString(dbIdMapList);
        linkComponentsDao.updateActivity(repoId, dbJson);
        LOGGER.info("db绑定环节操作成功");
    }

    /**
     * 取消绑定操作
     */
    @Override
    public void noBindUpdate(String repoId, String ids) {
        //分割字符串
        String[] strArr = ids.split(",");
        //db
        BwpActivityRepoEntity dbEntity = this.getOperation(repoId);
        String dbOperationList = dbEntity.getOperationList();
        //将列表转换为list
        List<Map<String, String>> dbIdMapList = JSONObject.parseObject(dbOperationList, new TypeToken<Object>() {
        }.getType());
        //遍历存入list
        for (String id : strArr) {
            for (int i = 0; i < dbIdMapList.size(); i++) {
                if (dbIdMapList.get(i).get("id").equals(id)) {
                    dbIdMapList.remove(i);
                }
            }
        }
        //list转json
        String dbJson = JSONArray.toJSONString(dbIdMapList);
        linkComponentsDao.updateActivity(repoId, dbJson);
        LOGGER.info("db取消绑定操作成功");
    }

    /**
     * db查重：环节名称
     */
    private void dbRepeatActivityName(Integer businessTypeId, String activityName, String repoId) {
        if (this.repeatActivityName(businessTypeId, activityName, repoId)) {
            throw new GlobalException(MessageFormat.format("环节名称:{0} 已存在", activityName));
        }
    }

    /**
     * db查重：绑定formId
     */
    private void dbCheckFormId(String repoId) {
        BwpActivityRepoEntity bwpActivityRepoEntities = this.checkFormId(repoId);
        Integer formId = bwpActivityRepoEntities.getFormId();
        if (formId != 0) {
            throw new GlobalException(MessageFormat.format("绑定formId:{0} 已存在", formId));
        }
    }
}


